#lang racket

;; By Spencer Hale

(require "Helper.scm")

(provide solveForceMove)

(define solveForceMove
  (lambda (matrix possvec pos1 pos2)
    (if (equal? (vector-ref (vector-ref matrix pos1) pos2) 0) ;check that position is unsolved
        (if(equal? (getposscount possvec pos1 pos2) 1) ;check if there is only one #t value in the possibility vector for this specific position
           (and (setpos matrix possvec pos1 pos2 (+ (vector-member #t (vector-ref (vector-ref possvec pos1) pos2)) 1)) ;sets the position to the available value
                (if(equal? pos2 8) ;if it has reached the end of the row
                   (if (equal? pos1 8) #f ;if it has reached the end of the entire matrix, return false
                       (solveForceMove matrix possvec (+ pos1 1) 0)) ;else, apply ForceMove to the first position in the next row
                   (and (solveForceMove matrix possvec pos1 (+ pos2 1)) #f)));if not at end of row, applyForceMove to the next position in the row
           (if(equal? pos2 8) ;There was more then one possibility for this position, move onto the next position.
              (if (equal? pos1 8) #f
                  (and (solveForceMove matrix possvec (+ pos1 1) 0) #f))
              (and (solveForceMove matrix possvec pos1 (+ pos2 1)) #f)))
        (if(equal? pos2 8) ;This position was already filled, if at the end of the matrix, return true;
           (if (equal? pos1 8) #t 
               (and (solveForceMove matrix possvec (+ pos1 1) 0) #t))
           (and (solveForceMove matrix possvec pos1 (+ pos2 1)) #t)))))

;counts how many possibilities are left for given position
(define getposscount
  (lambda (possvec pos1 pos2)
    (vector-count true? (vector-ref (vector-ref possvec pos1) pos2))))